import math
from datetime import timedelta

from fastapi import APIRouter, Depends, UploadFile, File, Form
from loguru import logger
from sqlalchemy.orm import Session
from starlette.requests import Request

from apis_module.jsonvo.reviews_vo import ReviewsListQueryModel, ReviewsViewModel, \
    ReviewsFormModel, ReviewsImagesRequest, ReviewsLikerRequest
from apis_module.service.reviews_service import ReviewsService
from config.env import JwtConfig
from config.get_db import get_db
from utils import time_format_util
from utils.response_util import response_200, response_500, response_400, response_401

reviewMapping = APIRouter()
reviewService = ReviewsService()


@reviewMapping.get('/reviews/look/{reviews_id}')
async def add_reviews_look(request: Request, reviews_id: str, db: Session = Depends(get_db)):
    """
    访问量监视，记录每个点评的点击量，前端埋点
    :param request:
    :param reviews_id:
    :param db:
    :return:
    """
    if reviews_id == '':
        return response_401(message='参数不能为空')
    try:
        result = ReviewsService.add_reviews_look_service(db, reviews_id)
        return response_200(data=result, message='操作成功')
    except Exception as e:
        logger.error(e)
        return response_500(data='', message='服务异常，请联系管理员')


@reviewMapping.post('/reviews/look')
async def reviews_look(request: Request, reviews_id: str):
    """
    访问量监视，记录每个点评的点击量，前端埋点[Redis版]
    :param request:
    :param reviews_id:
    :return:
    """
    if reviews_id == '':
        return response_400(message='参数不能为空')
    read_key = f'reviews_look:{reviews_id}'
    # 读取原有key的object
    result = await request.app.state.redis.get(read_key)
    if not result:
        await request.app.state.redis.set(read_key, 1,
                                          ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES))
    else:
        await request.app.state.redis.set(read_key, int(result) + 1,
                                          ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES))

    return response_200(data='', message='success')


@reviewMapping.post("/reviews/images/push")
def images_push_db(request: Request, images_data: ReviewsImagesRequest, query_db: Session = Depends(get_db)):
    try:
        result = reviewService.update_reviews_images_service(query_db, images_data)
        if result:
            logger.info('图片入库成功')
            return response_200(data=images_data, message='images saved')
    except Exception as e:
        logger.error(e)
        return response_500(data='', message='服务异常，请联系管理员')


@reviewMapping.post("/reviews/upload")
def upload_file(request: Request, picture_file: UploadFile = File(...), reviews_id: str = Form()):
    try:
        result = reviewService.upload_file_save(picture_file, reviews_id)
        if result:
            logger.info('保存成功')
            return response_200(data=result, message='upload success')
    except Exception as e:
        logger.error(e)
        return response_500(data='', message="服务异常，请联系管理员")


# def receive_upload_files(request: Request, files: List[UploadFile] = File(...), query_db: Session = Depends(get_db)):
#     pass

@reviewMapping.post("/reviews/create")
def create_reviews(request: Request, review_data: ReviewsFormModel, query_db: Session = Depends(get_db)):
    try:
        result = reviewService.create_reviews_service(query_db, review_data)
        if result:
            if review_data.is_release:
                logger.info('发布成功')
            else:
                logger.info('保存成功')

            return response_200(data=result, message='create success')
    except Exception as e:
        logger.error(e)
        return response_500(data='', message="服务异常，请联系管理员")


@reviewMapping.post("/reviews/list")
def get_reviews_list(request: Request, query_data: ReviewsListQueryModel, query_db: Session = Depends(get_db)):
    try:
        results = reviewService.get_reviews_list_service(query_db, query_data, is_all=True)
        results = time_format_util.list_format_datetime(results)
        liked_list = reviewService.get_liked_by_user_service(query_db, query_data.user_id)

        # 分页操作
        start = (query_data.page_num - 1) * query_data.page_size
        end = query_data.page_num * query_data.page_size
        page_results: list = results[start:end]
        total = len(results)
        has_next = True if math.ceil(len(results) / query_data.page_size) > query_data.page_num else False

        for review in page_results:
            if str(review.reviews_id) in liked_list:
                review.is_liked = True
            else:
                review.is_liked = False

        results_paginated = {
            "total": total,
            "has_next": has_next,
            "page_size": query_data.page_size,
            "page_num": query_data.page_num,
            "review_list": page_results,
        }

        logger.info('获取成功')
        return response_200(data=results_paginated, message="获取成功")
    except Exception as e:
        logger.error(e)
        return response_500(data='', message="服务异常，请联系管理员")


@reviewMapping.get("/reviews/{query_id}&{user_id}", response_model=ReviewsViewModel)
def get_reviews(request: Request, query_id: str, user_id: str, query_db: Session = Depends(get_db)):
    if query_id is None: return response_400(data="", message="参数为空请检查")
    if user_id is None: return response_401(data="", message="未授权请重新登录")
    try:
        result = reviewService.get_reviews_details(query_db, user_id, query_id)

        return response_200(data=result)
    except Exception as e:
        logger.error(e)
        return response_500(data='', message="服务异常，请联系管理员")


@reviewMapping.post("/revievs/update/liker")
def update_reviews_liker(request: Request, request_data: ReviewsLikerRequest, query_db: Session = Depends(get_db)):
    if request_data is None: return response_400(data="", message="参数为空请检查")
    try:
        result = reviewService.update_reviews_liker_service(query_db, request_data)

        return response_200(data='', message="更新成功")
    except Exception as e:
        logger.error(e)
        return response_500(data='', message="服务异常，请联系管理员")


@reviewMapping.get("/get/liker/{user_id}")
def get_liker(request: Request, user_id: str, query_db: Session = Depends(get_db)):
    if user_id is None:
        return response_400(data='', message='无用户授权或不是合法用户')
    else:
        liked_list = reviewService.get_liked_by_user_service(query_db, user_id)
        return response_200(data=liked_list, message='获取成功')
